package com.sakuraio.nextj.core.error;

import com.sakuraio.nextj.core.error.exception.BusinessException;
import com.sakuraio.nextj.core.error.exception.RequestValidationException;
import com.sakuraio.nextj.core.protocol.ErrorDetails;
import com.sakuraio.nextj.core.protocol.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * <p>ErrorUtils</p>
 *
 * @author nekoimi 2023/03/14
 */
public class ErrorUtils {
    private static final Logger logger = LoggerFactory.getLogger(ErrorUtils.class);

    private ErrorUtils() {
    }

    /**
     * 获取异常trace信息
     *
     * @param t 异常对象
     * @return
     */
    public static String trace(Throwable t) {
        StringWriter stackTrace = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stackTrace);
        t.printStackTrace(printWriter);
        return stackTrace.toString();
    }

    /**
     * 获取异常真实错误消息
     *
     * @param t
     * @return
     */
    public static String realMessage(Throwable t) {
        Throwable cause = t;
        while (cause.getCause() != null) {
            cause = cause.getCause();
        }
        return cause.getMessage();
    }

    /**
     * 业务异常
     *
     * @param errorDetails
     * @return
     */
    public static BusinessException business(ErrorDetails errorDetails) {
        return new BusinessException(errorDetails);
    }

    /**
     * 业务异常
     *
     * @return
     */
    public static BusinessException business(String message) {
        return new BusinessException(R.error(Errors.BUSINESS_EXCEPTION.code(), message).build());
    }

    /**
     * 请求参数验证异常
     *
     * @param message
     * @return
     */
    public static RequestValidationException validation(String message) {
        return new RequestValidationException(R.error(Errors.REQUEST_VALIDATION.code(), message).build());
    }

    /**
     * 业务异常
     *
     * @param errorDetails
     * @return
     */
    public static <E> Mono<E> reactiveBusiness(ErrorDetails errorDetails) {
        return Mono.error(business(errorDetails));
    }

    /**
     * 请求参数验证异常
     *
     * @param message
     * @return
     */
    public static <E> Mono<E> reactiveValidation(String message) {
        return Mono.error(validation(message));
    }

    /**
     * 记录错误信息
     *
     * @param format
     * @param arguments
     */
    public static void errorLog(String format, Object... arguments) {
        logger.error(format, arguments);
    }
}
